﻿using System.Diagnostics.Contracts;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Arachnophile
{
    /// <summary>
    /// XML processing extensions.
    /// </summary>
    public static class InfosetEx
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XDocument Xml(this byte[] source)
        {
            Contract.Requires(source != null);
            Contract.Ensures(Contract.Result<XDocument>() != null);

            return XDocument.Load(source.Stream());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static XDocument Xml(this string source)
        {
            Contract.Requires(source != null);
            Contract.Ensures(Contract.Result<XDocument>() != null);

            return XDocument.Parse(source);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IEnumerable<XElement> Root(this IEnumerable<XDocument> source)
        {
            Contract.Requires(source != null);
            Contract.Ensures(Contract.Result<IEnumerable<XElement>>() != null);

            return source.Select(x => x.Root);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IEnumerable<string> Value(this IEnumerable<XElement> source)
        {
            Contract.Requires(source != null);
            Contract.Ensures(Contract.Result<IEnumerable<string>>() != null);

            return from e in source
                   select e.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static IEnumerable<string> Value(this IEnumerable<XAttribute> source)
        {
            Contract.Requires(source != null);
            Contract.Ensures(Contract.Result<IEnumerable<string>>() != null);

            return from e in source
                   select e.Value;
        }
    }
}
